﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using VAdvantage.Utility;
using VAdvantage.Classes;
using System.Collections.Generic;
using System.Text;
using VAdvantage.Logging;

namespace VAdvantage.Model
{
    public class MLocationLookup : Lookup
    {
        System.Threading.Thread worker = null;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="ctx">context</param>
        /// <param name="WindowNo">WindowNo window no (to derive AD_Client/Org for new records)</param>
        public MLocationLookup(Ctx ctx, int windowNo)
            : base(ctx, windowNo, DisplayType.TableDir)
        {
            worker = new System.Threading.Thread(new System.Threading.ThreadStart(FillCacheList));
            worker.Start();
        }

        


        /// <summary>
        ///Get Display for Value (not cached)
        /// </summary>
        /// <param name="value">Location_ID</param>
        /// <returns>display Value</returns>
        public override String GetDisplay(Object value)
        {
            if (value == null || value == DBNull.Value)
                return null;
            MLocation loc = GetLocation(value, null);
            if (loc == null)
                return "<" + value.ToString() + ">";
            return loc.ToString();
        }

        /// <summary>
        ///Get Object of Key Value
        /// </summary>
        /// <param name="value">value</param>
        /// <returns></returns>
        public override NamePair Get(Object value)
        {
            if (value == null)
                return null;
            MLocation loc = GetLocation(value, null);
            if (loc == null)
                return null;
            return new KeyNamePair(loc.GetC_Location_ID(), loc.ToString());
        }

        /// <summary>
        /// The Lookup contains the key 
        /// <param name="key">Location_ID</param>
        /// <returns>true if key known</returns>
        public bool ContainsKey(Object key)
        {
            return GetLocation(key, null) == null;
        }   //  containsKey

        /// <summary>
        ///Get Location
        /// </summary>
        /// <param name="key">ID as string or integer</param>
        /// <param name="trxName">transaction</param>
        /// <returns>Location</returns>
        public MLocation GetLocation(Object key, String trxName)
        {
            if (key == null)
                return null;
            int C_Location_ID = 0;
            if (key is int)
                C_Location_ID = (int)key;
            else if (key != null)
                C_Location_ID = int.Parse(key.ToString());
            
            MLocation loc = GetLocation(C_Location_ID, trxName);
            if (loc != null)
            {
                if (C_Location_ID > 0)
                    MLookupStore.LocOfClientOrgCache[C_Location_ID] = loc.ToString();
            }
            return loc;
        }

        /// <summary>
        ///Get Location
        /// </summary>
        /// <param name="C_Location_ID">C_Location_ID id</param>
        /// <param name="trxName">transaction</param>
        /// <returns></returns>
        public MLocation GetLocation(int C_Location_ID, String trxName)
        {
            return MLocation.Get(GetCtx(), C_Location_ID, trxName);
        }


        /// <summary>
        ///Get underlying fully qualified Table.Column Name.
        ///	Used for VLookup.actionButton (Zoom)
        /// </summary>
        /// <returns>Column</returns>
        public override String GetColumnName()
        {
            return "C_Location_ID";
        }

        /// <summary>
        ///Return data as sorted Array - not implemented
        /// </summary>
        /// <param name="mandatory">mandatory</param>
        /// <param name="onlyValidated">only validated</param>
        /// <param name="onlyActive">only active</param>
        /// <param name="temporary">force load for temporary display</param>
        /// <returns></returns>
        public override List<NamePair> GetData(bool mandatory, bool onlyValidated, bool onlyActive, bool temporary)
        {
            List<NamePair> list = new List<NamePair>();
            if (!mandatory)
                list.Add(new KeyNamePair(-1, ""));
            //
            StringBuilder sql = new StringBuilder(
                    "SELECT C_Location_ID from C_Location WHERE AD_Client_ID = @ClientId AND (AD_Org_ID = 0 OR @parameter = 0)");
            if (onlyActive)
                sql.Append(" AND IsActive='Y'");
            sql.Append(" ORDER BY 1");
            System.Data.IDataReader dr = null;
            System.Data.SqlClient.SqlParameter[] param = null;
            try
            {
                param = new System.Data.SqlClient.SqlParameter[2];
                param[0] = new System.Data.SqlClient.SqlParameter("@ClientId", GetCtx().GetAD_Client_ID(_WindowNo));
                param[1] = new System.Data.SqlClient.SqlParameter("@parameter", GetCtx().GetAD_Org_ID(_WindowNo));

                dr = DataBase.DB.ExecuteReader(sql.ToString(), param);
                while (dr.Read())
                {
                    list.Add(Get(Utility.Util.GetValueOfInt(dr[0])));
                }
                dr.Close();
                dr = null;
                param = null;
            }
            catch (Exception e)
            {
                if (dr != null)
                {
                    dr.Close();
                    dr = null;
                    param = null;
                }
                log.Log(Level.SEVERE, sql.ToString(), e);
            }
            // Sort & return
            return list;
        }



        #region New 

        //do not run  In UI Thread 
        private void FillCacheList()
        {
            //List<NamePair> list = new List<NamePair>();
            //if (!mandatory)
            //    list.Add(new KeyNamePair(-1, ""));
            //
            StringBuilder sql = new StringBuilder(
                    "SELECT C_Location_ID from C_Location WHERE AD_Client_ID = @ClientId AND (AD_Org_ID = 0 OR @parameter = 0)");
            //if (onlyActive)
               // sql.Append(" AND IsActive='Y'");
            sql.Append(" ORDER BY 1");
            System.Data.IDataReader dr = null;
            System.Data.SqlClient.SqlParameter[] param = null;
            try
            {
                param = new System.Data.SqlClient.SqlParameter[2];
                param[0] = new System.Data.SqlClient.SqlParameter("@ClientId", GetCtx().GetAD_Client_ID(_WindowNo));
                param[1] = new System.Data.SqlClient.SqlParameter("@parameter", GetCtx().GetAD_Org_ID(_WindowNo));

                dr = DataBase.DB.ExecuteReader(sql.ToString(), param);
                int M_Location_ID = -1;
                while (dr.Read())
                {
                     M_Location_ID = Utility.Util.GetValueOfInt(dr[0]);
                    if(M_Location_ID>0)
                     MLookupStore.LocOfClientOrgCache[M_Location_ID ] =  GetLocation(M_Location_ID,null).ToString();
                }
                dr.Close();
                dr = null;
                param = null;
            }
            catch (Exception e)
            {
                if (dr != null)
                {
                    dr.Close();
                    dr = null;
                    param = null;
                }
                //og.Log(Level.SEVERE, sql.ToString(), e);
            }
            // Sort & return
        }
        //private volatile Dictionary<int, String> cacheAllLocationofClientOrg = new Dictionary<int, String>(5);



        public override string GetDisplayFromList(object key)
        {
            if (key == null || key == DBNull.Value || key.Equals(-1))
                return "";
            //
            Object display = GetFromList(key);
            if (display == null || display == DBNull.Value)
                return "<" + key.ToString() + ">";
            return display.ToString();
        }

        public override NamePair GetFromList(object key)
        {
            NamePair nm = null;
            if (key is int)
            {
                string loc;
               int  M_Location_ID = int.Parse(key.ToString());

                MLookupStore.LocOfClientOrgCache.TryGetValue(M_Location_ID, out loc);
                
                if (loc != null)
                {
                    nm = new KeyNamePair(M_Location_ID, loc);
                    return nm;
                }
                else
                {
                    //AddInList(M_Location_ID);
                }
            }
            return nm;

        }

        private void AddInList(int M_Location_ID)
        {
            //if (worker.IsAlive)
            //{
            //    System.Threading.Thread.Sleep(100);
            //    return;
            //}
            //System.Threading.ThreadPool.QueueUserWorkItem(delegate
            //{
            //    MLocation loc = GetLocation(M_Location_ID, null);
            //    if (loc != null)
            //    {
            //        cacheAllLocationofClientOrg[M_Location_ID] = loc.ToString();
            //    }
            //});
        }

#endregion


        public override void Dispose()
        {

            if (worker.IsAlive)
            {
                try
                {
                    worker.Abort();
                    worker = null;
                }
                catch
                {
                    worker = null;
                }
            }

            //if (cacheAllLocationofClientOrg != null) 
            //{
            //    cacheAllLocationofClientOrg.Clear();
            //}
            //cacheAllLocationofClientOrg = null;



            base.Dispose();
        }
    }
}
